package com.ydlclass.loadbalance.loadbalancer;

import com.ydlclass.configuration.YrpcConfiguration;
import com.ydlclass.configuration.YrpcConfigurationHolder;
import com.ydlclass.loadbalance.LoadBalancer;
import com.ydlclass.loadbalance.Selector;
import com.ydlclass.message.MetaData;
import com.ydlclass.message.YrpcMessage;
import com.ydlclass.registry.Registry;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 随机的负载均衡算法
 *
 * @author it楠老师
 * @createTime 2023-03-09
 */
@Slf4j
public class RandomLoadBalancer implements LoadBalancer {

    private Map<String, RandomSelector> selectors = new ConcurrentHashMap<>(32);

    @Override
    public InetSocketAddress selectServiceAddress(List<InetSocketAddress> serviceInetSocketAddress, YrpcMessage yrpcMessage) {
        if(yrpcMessage.getPayload() instanceof MetaData metaData) {
            String serviceName = metaData.getInterfaceName();
            RandomSelector randomSelector = selectors.get(serviceName);
            if(randomSelector == null){
                YrpcConfiguration yrpcConfiguration = YrpcConfigurationHolder.get();
                Registry registry = yrpcConfiguration.getRegistry();
                List<InetSocketAddress> serviceList = registry.lookup(serviceName);

                randomSelector = new RandomSelector(serviceList);
                selectors.put(serviceName,randomSelector);
            }
            if(log.isDebugEnabled()){
                log.debug("balancing --> The round robin algorithm is being used for load balancing.");
            }
            return randomSelector.getNext(yrpcMessage);

        }

        return null;
    }

    /**
     * 使用chatGpt生成的轮询算法
     */
    private static class RandomSelector implements Selector {
        private List<InetSocketAddress> serviceList; // 存储服务节点的列表

        // 构造函数，传入服务节点列表
        public RandomSelector(List<InetSocketAddress> serviceList) {
            this.serviceList = serviceList;
        }


        // 获取下一个服务节点
        @Override
        public InetSocketAddress getNext(YrpcMessage yrpcMessage) {
            // 如果节点列表为空，返回null
            if (serviceList == null || serviceList.isEmpty()) {
                return null;
            }

            // 这里的算法是为了后期的权重留个口子
            int totalWeight = serviceList.size();

            // 获取当前计数器的值，并增加1
            int random = new Random().nextInt(totalWeight) + 1;

            // 1是默认的权重，后续在该
            for (InetSocketAddress inetSocketAddress : serviceList) {
                if(random <= 1){
                    return inetSocketAddress;
                }
                random -= 1;
            }

            // 返回当前索引对应的服务节点，这里使用取模操作，确保索引在节点列表范围内
            return null;
        }

        @Override
        public void reload(String serviceName, List<InetSocketAddress> newServiceList) {

        }

    }

}
